from fastapi import APIRouter, Depends, Query, Request
from starlette.responses import HTMLResponse
from tortoise.expressions import Q
from tortoise.transactions import atomic

from applications.common.render_template import templates
from applications.common.user_manager import permission_depends
from applications.utils.http import PageResponse, ResultResponse, fail_api, success_api, table_api
from applications.models import DictData, DictType
from applications.schemas.admin_dict import (
    DictDataBatchRemoveModel,
    DictDataEnableModel,
    DictDataSaveModel,
    DictDataUpdateModel,
    DictTypeBatchRemoveModel,
    DictTypeEnableModel,
    DictTypeOutSchema,
    DictTypeSaveModel,
    DictTypeUpdateModel,
    DictDataOutSchema,
)

route = APIRouter(prefix="/dict", tags=["数据字典"])


# 数据字典
@route.get(
    "/",
    dependencies=[Depends(permission_depends("system:dict:main"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def main(request: Request):
    return templates.TemplateResponse("system/dict/main.html", {"request": request})


@route.get(
    "/dictType/data",
    dependencies=[Depends(permission_depends("system:dict:main"))],
    summary="获取字典类型数据",
    response_model=PageResponse[DictTypeOutSchema],
)
async def dict_type_data(type_name: str = Query(None, alias="typeName"), page: int = Query(1), limit: int = Query(10)):
    # 查询参数构造
    query = Q()
    if type_name:
        query &= Q(type_name__icontains=type_name)

    # orm查询
    dict_types = await DictType.filter(query).offset((page - 1) * limit).limit(limit).all()
    count = await DictType.filter(query).count()

    return table_api(data=dict_types, count=count)


@route.get(
    "/dictType/add",
    dependencies=[Depends(permission_depends("system:dict:add"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def dict_type_add(request: Request):
    return templates.TemplateResponse("system/dict/add.html", {"request": request})


@route.post(
    "/dictType/save",
    dependencies=[Depends(permission_depends("system:dict:add"))],
    summary="保存字典类型",
    response_model=ResultResponse,
)
async def dict_type_save(data: DictTypeSaveModel):
    dict_type = DictType(**data.model_dump())
    await dict_type.save()

    if dict_type.id is None:
        return fail_api(msg="增加失败")
    return success_api(msg="增加成功")


#  编辑字典类型
@route.get(
    "/dictType/edit",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def dict_type_edit(request: Request, dictTypeId: int = Query(...)):
    dict_type = await DictType.get_or_none(id=dictTypeId)
    return templates.TemplateResponse("system/dict/edit.html", {"request": request, "dict_type": dict_type})


#  编辑字典类型
@route.put(
    "/dictType/update",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    summary="更新字典类型",
    response_model=ResultResponse,
)
async def dict_type_update(data: DictTypeUpdateModel):
    dict_type = await DictType.get_or_none(id=data.id)
    if not dict_type:
        return fail_api(msg="字典类型不存在")
    await dict_type.update_from_dict(data.model_dump())
    await dict_type.save()
    return success_api(msg="更新成功")


# 启用字典
@route.put(
    "/dictType/enable",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    summary="启用字典类型",
    response_model=ResultResponse,
)
async def dict_type_enable(data: DictTypeEnableModel):
    dict_type = await DictType.get_or_none(id=data.id)
    if not dict_type:
        return fail_api(msg="字典类型不存在")

    dict_type.enable = 1
    await dict_type.save()
    return success_api(msg="启用成功")


# 禁用字典
@route.put(
    "/dictType/disable",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    summary="禁用字典类型",
    response_model=ResultResponse,
)
async def dict_type_dis_enable(data: DictTypeEnableModel):
    dict_type = await DictType.get_or_none(id=data.id)
    if not dict_type:
        return fail_api(msg="字典类型不存在")

    dict_type.enable = 0
    await dict_type.save()
    return success_api(msg="禁用成功")


# 删除字典类型
@route.delete(
    "/dictType/remove/{pk}",
    dependencies=[Depends(permission_depends("system:dict:remove"))],
    summary="删除字典类型",
    response_model=ResultResponse,
)
@atomic()
async def dict_type_delete(pk: int):
    dict_type = await DictType.get_or_none(id=pk)
    if not dict_type:
        return fail_api(msg="删除失败")

    # 删除关联的字典数据
    await DictData.filter(type_code=dict_type.type_code).delete()

    await dict_type.delete()
    return success_api(msg="删除成功")


@route.get(
    "/dictData/data",
    dependencies=[Depends(permission_depends("system:dict:main"))],
    summary="获取字典数据",
    response_model=PageResponse[DictDataOutSchema],
)
async def dict_code_data(type_code: str = Query(None, alias="typeCode"), page: int = Query(1), limit: int = Query(10)):
    query = Q()
    if type_code:
        query &= Q(type_code=type_code)

    dict_data = await DictData.filter(query).offset((page - 1) * limit).limit(limit).all()
    count = await DictData.filter(query).count()
    return table_api(data=dict_data, count=count)


# 增加字典数据
@route.get(
    "/dictData/add",
    dependencies=[Depends(permission_depends("system:dict:add"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def dict_data_add(request: Request, typeCode: str = Query(None)):
    return templates.TemplateResponse("system/dict/data/add.html", {"request": request, "type_code": typeCode})


# 增加字典数据
@route.post(
    "/dictData/save",
    dependencies=[Depends(permission_depends("system:dict:add"))],
    summary="保存字典数据",
    response_model=ResultResponse,
)
async def dict_data_save(data: DictDataSaveModel):
    dict_data = DictData(**data.model_dump())
    await dict_data.save()

    if not dict_data.id:
        return fail_api(msg="增加失败")
    return success_api(msg="增加成功")


#  编辑字典数据
@route.get(
    "/dictData/edit",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def dict_data_edit(request: Request, dataId: int = Query(...)):
    dict_data = await DictData.get_or_none(id=dataId)
    return templates.TemplateResponse("system/dict/data/edit.html", {"request": request, "dict_data": dict_data})


#  编辑字典数据
@route.put(
    "/dictData/update",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    summary="更新字典数据",
    response_model=ResultResponse,
)
async def dict_data_update(data: DictDataUpdateModel):
    dict_data = await DictData.get_or_none(id=data.data_id)
    if not dict_data:
        return fail_api(msg="字典数据不存在")
    await dict_data.update_from_dict(data.model_dump(exclude={"data_id"}))
    await dict_data.save()
    return success_api(msg="更新成功")


# 启用字典数据
@route.put(
    "/dictData/enable",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    summary="启用字典数据",
    response_model=ResultResponse,
)
async def dict_data_enable(data: DictDataEnableModel):
    dict_data = await DictData.get_or_none(id=data.dataId)
    if not dict_data:
        return fail_api(msg="字典数据不存在")

    dict_data.enable = 1
    await dict_data.save()
    return success_api(msg="启用成功")


# 禁用字典数据
@route.put(
    "/dictData/disable",
    dependencies=[Depends(permission_depends("system:dict:edit"))],
    summary="禁用字典数据",
    response_model=ResultResponse,
)
async def dict_data_disenable(data: DictDataEnableModel):
    dict_data = await DictData.get_or_none(id=data.dataId)
    if not dict_data:
        return fail_api(msg="字典数据不存在")

    dict_data.enable = 0
    await dict_data.save()
    return success_api(msg="禁用成功")


# 删除字典数据
@route.delete(
    "/dictData/remove/{pk}",
    dependencies=[Depends(permission_depends("system:dict:remove"))],
    summary="删除字典数据",
    response_model=ResultResponse,
)
@atomic()
async def dict_data_delete(pk: int):
    dict_data = await DictData.get_or_none(id=pk)
    if not dict_data:
        return fail_api(msg="删除失败")

    await dict_data.delete()
    return success_api(msg="删除成功")


# 批量删除字典类型
@route.delete(
    "/dictData/batchRemoveDictType",
    dependencies=[Depends(permission_depends("system:dict:remove"))],
    summary="批量删除字典类型",
    response_model=ResultResponse,
)
@atomic()
async def dict_type_batch_remove(data: DictTypeBatchRemoveModel):
    dict_types = await DictType.filter(id__in=data.ids).all()
    for dict_type in dict_types:
        # 删除关联的字典数据
        await DictData.filter(type_code=dict_type.type_code).delete()
        await dict_type.delete()

    return success_api(msg="删除成功")


# 批量删除字典数据
@route.delete(
    "/dictData/batchRemoveDictData",
    dependencies=[Depends(permission_depends("system:dict:remove"))],
    summary="批量删除字典数据",
    response_model=ResultResponse,
)
@atomic()
async def dict_data_batch_remove(data: DictDataBatchRemoveModel):
    dict_data_list = await DictData.filter(id__in=data.ids).all()
    for dict_data in dict_data_list:
        await dict_data.delete()

    return success_api(msg="删除成功")
